package vip.xiaonuo.smzq.core.utils;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;

import org.apache.commons.collections4.map.LinkedMap;
import org.geotools.geometry.jts.JTS;
import org.geotools.geometry.jts.JTSFactoryFinder;
import org.geotools.referencing.CRS;
import org.locationtech.jts.geom.*;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.referencing.FactoryException;
import org.opengis.referencing.crs.CRSAuthorityFactory;
import org.opengis.referencing.crs.CRSFactory;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.operation.MathTransform;
import org.opengis.referencing.operation.TransformException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import vip.xiaonuo.smzq.modular.kcl.entity.vo.KqfwCoordinates;
import vip.xiaonuo.smzq.modular.lifecycle.util.CoordinateTranUtil;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 投影转换工具
 *
 * @author liuliya
 */
@Component
public class TransFormUtil {

    @Resource
    CoordinateTranUtil coordinateTranUtil;
    //十进制经度
    public static final String LNG_PATTERN = "^[\\-\\+]?(0(\\.\\d{1,14})?|([1-9](\\d)?)(\\.\\d{1,14})?|1[0-7]\\d{1}(\\.\\d{1,14})?|180(\\.0{1,14})?)$";
    //纬度
    public static final String LAT_PATTERN = "^[\\-\\+]?((0|([1-8]\\d?))(\\.\\d{1,14})?|90(\\.0{1,14})?)$";
    /*
     * 度分秒正则
     * 每节的数字不能以 0 开头（比如不能写 08度，而要写 8 度）；
     * 秒的数字可以是小数，小数点后最多有两位数字；
     * 分隔三个节的标志符可以是空格、中横线、逗号、分号、°′"或者度分秒；
     * 取值范围，经度为 0度0分0秒 至 180度0分0秒；纬度为 0度0分0秒 至 90度0分0秒。
     * */
    //经度
    public static final String LNG_PATTERN_D = "^((\\d|[1-9]\\d|1[0-7]\\d)[°](\\d|[0-5]\\d)[′](\\d|[0-5]\\d)(\\.\\d{1,6})?[\\″]$)|(180[°]0[′]0[\\″]$)";
    //纬度
    public static final String LAT_PATTERN_D = "^((\\d|[1-8]\\d)[°](\\d|[0-5]\\d)[′](\\d|[0-5]\\d)(\\.\\d{1,6})?[\\″]$)|(90[°]0[′]0[\\″]$)";
    // WGS84标准参考椭球中的地球长半径(单位:米)
    private static final double EARTH_RADIUS_WGS84 = 6378137.0;

    /**
     * 计算两个坐标的距离(粗略计算，单位:米)
     * 计算公式参照 google map 的距离计算
     *
     * @param lat1 坐标1纬度
     * @param lng1 坐标1经度
     * @param lat2 坐标2纬度
     * @param lng2 坐标2经度
     * @return
     */
    public static double distance(double lat1, double lng1, double lat2, double lng2) {
        double radLat1 = Math.toRadians(lat1);
        double radLat2 = Math.toRadians(lat2);

        double a = radLat1 - radLat2;
        double b = Math.toRadians(lng1) - Math.toRadians(lng2);

        double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) +
                Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)));
        return Math.round(s * EARTH_RADIUS_WGS84);
    }

    /*
     * 坐标/投影之间的转换
     * */

    /**
     * 坐标转换
     *
     * @param y
     * @param x
     * @param dh
     * @return
     * @throws Exception
     */
    public static double[] transTo4490fromProjectionByEpsg(double x, double y, String dh) throws Exception {
        String epsgSource = "";
        switch (dh) {
            //6度分带
            case "13":
                epsgSource = "EPSG:4491";
                break;
            case "14":
                epsgSource = "EPSG:4492";
                break;
            case "15":
                epsgSource = "EPSG:4493";
                break;
            case "16":
                epsgSource = "EPSG:4494";
                break;
            case "17":
                epsgSource = "EPSG:4495";
                break;
            case "18":
                epsgSource = "EPSG:4496";
                break;
            case "19":
                epsgSource = "EPSG:4497";
                break;
            case "20":
                epsgSource = "EPSG:4498";
                break;
            case "21":
                epsgSource = "EPSG:4499";
                break;
            case "22":
                epsgSource = "EPSG:4500";
                break;
            case "23":
                epsgSource = "EPSG:4501";
                break;
            //3度分带
            case "25":
                epsgSource = "EPSG:4513";
                break;
            case "26": //
                epsgSource = "EPSG:4514";
                break;
            case "27": //
                epsgSource = "EPSG:4515";
                break;
            case "28":  //
                epsgSource = "EPSG:4516";
                break;
            case "29":  //
                epsgSource = "EPSG:4517";
                break;
            case "30":  //
                epsgSource = "EPSG:4518";
                break;
            case "31":  //
                epsgSource = "EPSG:4519";
                break;
            case "32":  //
                epsgSource = "EPSG:4520";
                break;
            case "33":  //
                epsgSource = "EPSG:4521";
                break;
            case "34":   //
                epsgSource = "EPSG:4522";
                break;
            case "35":   //
                epsgSource = "EPSG:4523";
                break;
            case "36":  //
                epsgSource = "EPSG:4524";
                break;
            case "37":  //
                epsgSource = "EPSG:4525";
                break;
            case "38":   //'EPSG:':
                epsgSource = "EPSG:4526";
                break;
            case "39"://'EPSG:':
                epsgSource = "EPSG:4527";
                break;
            case "40"://'EPSG:':
                epsgSource = "EPSG:4528";
                break;
            case "41"://'EPSG:':
                epsgSource = "EPSG:4529";
                break;
            case "42"://'EPSG:':
                epsgSource = "EPSG:4530";
                break;
            case "43"://'EPSG:':
                epsgSource = "EPSG:4531";
                break;
            case "44"://'EPSG:':
                epsgSource = "EPSG:4532";
                break;
            case "45"://'EPSG:':
                epsgSource = "EPSG:4533";
                break;
        }
        return transFromByEpsg(x, y, epsgSource, "EPSG:4490");
    }

    /**
     * 坐标投影转换
     *
     * @param x
     * @param y
     * @param epsgSource
     * @param epsgTarget
     * @return
     * @throws Exception
     */
    public static double[] transFromByEpsg(double x, double y, String epsgSource, String epsgTarget) throws Exception {
        Coordinate sourceCoord = new Coordinate(y, x);
        Coordinate targetCoord = new Coordinate(0, 0);
        try {
            CoordinateReferenceSystem crsSource = CRS.decode(epsgSource);
            CoordinateReferenceSystem crsTarget = CRS.decode(epsgTarget);
            MathTransform transform = CRS.findMathTransform(crsSource, crsTarget);
            JTS.transform(sourceCoord, targetCoord, transform);
            double[] targetCoords = {targetCoord.x, targetCoord.y};
            return targetCoords;
        } catch (TransformException te) {
            throw new Exception("坐标系转换错误：TransformException:" + te.getMessage());
        } catch (FactoryException fe) {
            throw new Exception("坐标系转换错误：FactoryException:" + fe.getMessage());
        } catch (Exception e) {
            throw new Exception("坐标系转换错误：Exception:" + e.getMessage());
        }
    }

    /**
     * 度分秒转十进制度
     *
     * @param jwd
     * @return
     */
    public static String Dms2D(String jwd) {
        if (StrUtil.isNotEmpty(jwd) && (jwd.contains("°"))) {//如果不为空并且存在度单位
            //计算前进行数据处理
            jwd = jwd.replace("E", "").replace("N", "").replace(":", "").replace("：", "");
            double d = 0, m = 0, s = 0;
            d = Double.parseDouble(jwd.split("°")[0]);
            //不同单位的分，可扩展
            if (jwd.contains("′")) {//正常的′
                m = Double.parseDouble(jwd.split("°")[1].split("′")[0]);
            } else if (jwd.contains("'")) {//特殊的'
                m = Double.parseDouble(jwd.split("°")[1].split("'")[0]);
            }
            //不同单位的秒，可扩展
            if (jwd.contains("″")) {//正常的″
                //有时候没有分 如：112°10.25″
                s = jwd.contains("′") ? Double.parseDouble(jwd.split("′")[1].split("″")[0]) : Double.parseDouble(jwd.split("°")[1].split("″")[0]);
            } else if (jwd.contains("''")) {//特殊的''
                //有时候没有分 如：112°10.25''
                s = jwd.contains("'") ? Double.parseDouble(jwd.split("'")[1].split("''")[0]) : Double.parseDouble(jwd.split("°")[1].split("''")[0]);
            }
            jwd = String.valueOf(d + m / 60 + s / 60 / 60);//计算并转换为string
        }
        return jwd;
    }

    /**
     * 将要素的坐标系转为相对应的坐标系
     *
     * @param feature    要素类
     * @param targetSrid 坐标系id
     * @return
     */
    public static Geometry coordinateTransform(SimpleFeature feature, int targetSrid) {
        if (ObjectUtil.isNull(feature)) {
            return null;
        }
        try {
            CRSAuthorityFactory factory = CRS.getAuthorityFactory(true);
            CoordinateReferenceSystem target = factory.createCoordinateReferenceSystem("EPSG:" + targetSrid);
            CoordinateReferenceSystem coordinateReferenceSystem = feature.getDefaultGeometryProperty().getDescriptor().getCoordinateReferenceSystem();
            if (coordinateReferenceSystem == null) {
                Geometry res = (Geometry) feature.getDefaultGeometry();
                res.setSRID(targetSrid);
                return res;
            }
            MathTransform transform = CRS.findMathTransform(coordinateReferenceSystem, target, true);
            Geometry res = JTS.transform((Geometry) feature.getDefaultGeometry(), transform);
            if (res != null) {
                res.setSRID(targetSrid);
            }
            return res;
        } catch (FactoryException | TransformException e) {
            e.printStackTrace();
        }
        return null;
    }

    /*
     * 解析点坐标的类型
     * */

    /**
     * 获取坐标解析类型 1.十进制度、2.度分秒、3.投影 0.错误类型
     *
     * @param pointIndex1 坐标x y数组
     * @return
     */
    public static Integer polygonAnalysis_type(String[] pointIndex1) {
        if (pointIndex1.length != 2) {
            return 0;
        }
        Point pointDecimalism = pointDecimalism(pointIndex1[0], pointIndex1[1]);
        Point pointDFM = pointDFM(pointIndex1[0], pointIndex1[1]);
        Point pointEPSG4490 = pointEPSG4490(pointIndex1[0], pointIndex1[1]);
        if (ObjectUtil.isNotNull(pointDecimalism)) {
            return 1;
        }
        if (ObjectUtil.isNotNull(pointDFM)) {
            return 2;
        }
        if (ObjectUtil.isNotNull(pointEPSG4490)) {
            return 3;
        }
        return 0;
    }

    /**
     * 根据解析类型创建点 (面解析方法中使用)
     *
     * @param pointStr     坐标点x y数组
     * @param analysisType 解析类型 1.十进制度、2.度分秒、3.投影
     * @return
     */
    public static Point polygonAnalysis_point(String[] pointStr, Integer analysisType) {
        //根据得到的类型解析每个点
        switch (analysisType) {
            case 1:
                return pointDecimalism(pointStr[0], pointStr[1]);
            case 2:
                return pointDFM(pointStr[0], pointStr[1]);
            case 3:
                return pointEPSG4490(pointStr[0], pointStr[1]);
        }
        return null;
    }

    /**
     * 创建点坐标
     *
     * @param x 经度
     * @param y 纬度
     * @return
     */
    private static Point createPoint(Double x, Double y) {
        //创建几何工厂
        GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory();
        //创建一个几何坐标
        Coordinate coordinate = new Coordinate(x, y);
        return geometryFactory.createPoint(coordinate);
    }

    /**
     * 检查输入的十进制度点坐标
     *
     * @param x 经度
     * @param y 纬度
     */
    public static Point pointDecimalism(String x, String y) {
        if (!(BasicUtil.isDouble(x, LNG_PATTERN) && BasicUtil.isDouble(y, LAT_PATTERN))) {
            return null;
        }
        return createPoint(Double.parseDouble(x), Double.parseDouble(y));
    }

    /**
     * 检查输入的度分秒点坐标
     *
     * @param x 经度
     * @param y 纬度
     */
    public static Point pointDFM(String x, String y) {
        if (!(BasicUtil.isPattern(x, LNG_PATTERN_D) && BasicUtil.isPattern(y, LAT_PATTERN_D))) {
            return null;
        }
        //转为十进制度BasicUtil
        double lon = Double.parseDouble(Dms2D(x));
        double lat = Double.parseDouble(Dms2D(y));
        return createPoint(lon, lat);
    }

    /**
     * 检查输入的2000大地点坐标
     *
     * @param x 经度
     * @param y 纬度
     */
    public static Point pointEPSG4490(String x, String y) {
        try {
            double[] doubles = transTo4490fromProjectionByEpsg(Double.parseDouble(x), Double.parseDouble(y), y.substring(0, 2));
            return createPoint(doubles[0], doubles[1]);
        } catch (Exception e) {
            return null;
        }
    }


    /*
     * 面坐标之间的转换
     * CoordinateDisposeWKT1
     * CoordinateDisposeWKT2
     * CoordinateDisposeWKT3
     * CoordinateDisposeWKT4
     * */

    /**
     * 面坐标处理解析成WKT格式
     * 第一种方式
     *
     * @param coordinatesStr 一串坐标
     * @return 4348121.92, 38610084.30
     * 4348076.60,38611233.20
     * 4347543.64,38611157.40
     * 4347515.09,38611985.26
     * 4346651.97,38612040.25
     * 4346493.69,38611280.02
     * 4346043.13,38610778.17
     * 4345917.48,38609708.95
     * 4346602.51,38609067.42
     */
    public static String CoordinateDisposeWKT1(String coordinatesStr) {
        coordinatesStr = coordinatesStr.trim().replaceAll("\\s+", "\n");
        //分割文本获取所有的点坐标
        String[] pointCollection = coordinatesStr.split("[\t\n\r]");
        //一个面最少三个点
        if (pointCollection.length < 3) {
            return null;
        }
        //判断当前坐标串用那种方式解析1.十进制度、2.度分秒、3.投影
        Integer analysisType = polygonAnalysis_type(pointCollection[0].trim().split(","));
        //存储创建好的点坐标几何
        Coordinate[] coordinates = new Coordinate[pointCollection.length];
        //循环每个坐标，验真坐标的正确性
        for (int i = 0; i < pointCollection.length; i++) {
            //根据","分割x y
            String[] pointStr = pointCollection[i].trim().split(",");
            if (pointStr.length != 2) {
                return null;
            }
            Point point = polygonAnalysis_point(pointStr, analysisType);
            //其中有一个点存在错误该图形不正确
            if (ObjectUtil.isNull(point)) {
                return null;
            }
            //创建点几何
            coordinates[i] = point.getCoordinate();
        }
        Polygon polygon = GeometryUtil.createPolygon(coordinates);
        //创建多面类型
        MultiPolygon multiPolygon = GeometryUtil.createMultiPolygon(new Polygon[]{polygon});
        //检查图形的有效性
        if (!multiPolygon.isValid()) {
            return null;
        }
        return multiPolygon.toString();
    }

    /**
     * 面坐标处理解析成WKT格式
     * 第二种方式
     *
     * @param coordinatesStr 一串坐标
     * @return 1, 4203487.48, 38515918.33, ,
     * 2,4203491.25,38516654.34, ,
     * 3,4203431.04,38516773.13, ,
     * 4,4203336.43,38516829.18, ,
     * 5,4203273.42,38516862.76, ,
     * 6,4203217.14,38516856.54, ,
     * 7,4203189.85,38516751.12, ,
     * 8,4203189.85,38516663.19, ,
     * 9,4203093.83,38516717.14, ,
     * 10,4203050.36,38516838.10, ,
     * 11,4202394.67,38516765.61, ,
     * 12,4202312.69,38516211.71, ,
     * *,632.5,350, ,1
     */
    public static String CoordinateDisposeWKT2(String coordinatesStr) {
        String[] coordinatesArry = coordinatesStr.replaceAll(" ", "").split(",");
        //判断当前坐标串用那种方式解析1.十进制度、2.度分秒、3.投影
        Integer analysisType = polygonAnalysis_type(new String[]{coordinatesArry[1], coordinatesArry[2]});
        //坐标面集合
        Map<List<Coordinate>, Integer> CoordinateList = new LinkedMap<>();
        //坐标点集合
        List<Coordinate> pointList = new ArrayList<>();
        //坐标解析
        for (int i = 3; i < coordinatesArry.length; i += 4) {
            String sign = coordinatesArry[i - 3];
            sign = sign.trim();
            //结束符
            if ("*".equals(sign)) {
                String[] end = coordinatesArry[i + 1].split(" ");
                CoordinateList.put(pointList, Integer.parseInt(end[0]));
                pointList = new ArrayList<>();
                continue;
            }
            String x = coordinatesArry[i - 2].trim();
            String y = coordinatesArry[i - 1].trim();
            Point point = polygonAnalysis_point(new String[]{x, y}, analysisType);
            pointList.add(point.getCoordinate());
        }
        //坐标转为面
        List<List<Polygon>> multiPolygonList = new ArrayList<>();
        List<Polygon> polygonList = new ArrayList<>();
        for (List<Coordinate> k : CoordinateList.keySet()) {
            //获取结束值
            Integer v = CoordinateList.get(k);
            Coordinate[] coordinates = new Coordinate[k.size()];
            Polygon polygon = GeometryUtil.createPolygon(k.toArray(coordinates));
            if (v == 1) {
                multiPolygonList.add(polygonList);
                polygonList = new ArrayList<>();
            }
            polygonList.add(polygon);
        }
        multiPolygonList.remove(0);
        multiPolygonList.add(polygonList);
        //处理多面或面带洞
        polygonList = new ArrayList<>();
        for (List<Polygon> list : multiPolygonList) {
            if (list.size() <= 1) {
                polygonList.addAll(list);
                continue;
            }
            LinearRing[] linearRings = new LinearRing[list.size() - 1];
            for (int i = 1; i < list.size(); i++) {
                linearRings[i - 1] = list.get(i).getExteriorRing();
            }
            Polygon polygonWithHoles = GeometryUtil.createPolygonWithHoles(list.get(0).getExteriorRing(), linearRings);
            polygonList.add(polygonWithHoles);
        }
        //创建多面
        Polygon[] polygons = new Polygon[polygonList.size()];
        MultiPolygon multiPolygon = GeometryUtil.createMultiPolygon(polygonList.toArray(polygons));
        return multiPolygon.toString();
    }

    /**
     * 面坐标处理解析成WKT格式
     * 第三种方式
     *
     * @param coordinatesStr 一串坐标
     * @return
     * 2,
     * 5,
     * 1,4421028.05,39571109.36,
     * 2,4421062.05,39571064.36,
     * 3,4421110.05,39571178.36,
     * 4,4421088.05,39571236.36,
     * 5,4421024.05,39571217.36,
     * 103,47,,1,
     * 3,
     * 6,4420876.05,39571372.36,
     * 7,4420967.05,39571412.36,
     * 8,4420819.05,39571421.36,
     * 103,47,,1,
     */
    public static String CoordinateDisposeWKT3(String coordinatesStr) {
        try {
            String[] coordinatesArry = coordinatesStr.replaceAll(" ", "").split(",");
           if (coordinatesArry.length < 5){
               return null;
           }

            //判断当前坐标串用那种方式解析1.十进制度、2.度分秒、3.投影
            Integer analysisType = polygonAnalysis_type(new String[]{coordinatesArry[3], coordinatesArry[4]});
            //面的个数
            Integer polygonNum = Integer.parseInt(coordinatesArry[0]);
            //第一个面的点个数
            Integer pointNum = Integer.parseInt(coordinatesArry[1]);
            //第一个X点
            Integer x = 3;
            //第一个Y点
            Integer y = 4;
            //存放多个面
            List<Polygon> multiPolygonList = new ArrayList<>();
            //存放为洞的面
            List<Polygon> holePolygon = new ArrayList<>();
            for (int i = 0; i < polygonNum; i++) {
                Coordinate[] coordinates = new Coordinate[pointNum];
                for (int j = 0; j < pointNum; j++, x += 3, y += 3) {
                    //x点
                    String lon = coordinatesArry[x];
                    //y点
                    String lat = coordinatesArry[y];
                    //转为点
                    Point point = polygonAnalysis_point(new String[]{lon, lat}, analysisType);
                    coordinates[j] = point.getCoordinate();
                }
                //创建面
                Polygon polygon = GeometryUtil.createPolygon(coordinates);
                //判断是多面或带洞的面
                Integer type = Integer.parseInt(coordinatesArry[y + 1]);
                if (type == -1) {
                    holePolygon.add(polygon);
                } else {
                    multiPolygonList.add(polygon);
                }
                if (i < polygonNum - 1) {
                    //第二个或更多面的点数
                    pointNum = Integer.parseInt(coordinatesArry[y + 2]);
                    x += 5;
                    y += 5;
                }
            }

            MultiPolygon multiPolygon = GeometryUtil.createMultiPolygon(multiPolygonList.toArray(new Polygon[multiPolygonList.size()]));
            //存在带洞的情况
            if (holePolygon.size() != 0) {
                List<LinearRing> linearRingList = holePolygon.stream().map(Polygon::getExteriorRing).collect(Collectors.toList());
                //创建带洞的面
                Coordinate[] coordinates = multiPolygon.getCoordinates();
                GeometryFactory geometryFactory = new GeometryFactory();
                LinearRing ring = geometryFactory.createLinearRing(coordinates);
                Polygon polygonWithHoles = GeometryUtil.createPolygonWithHoles(ring, linearRingList.toArray(new LinearRing[holePolygon.size()]));
                multiPolygon = GeometryUtil.createMultiPolygon(new Polygon[]{polygonWithHoles});
            }
            //检查图形的有效性
//        if (!multiPolygon.isValid()) {
//            return null;
//        }
            return multiPolygon.toString();
        } catch (Exception e) {
            e.printStackTrace();
        }


        return null;
    }

    /**
     * 面坐标处理解析成WKT格式
     * 第四种方式
     *
     * @param coordinatesStr 一串坐标
     * @return 2, 4,
     * 114.0643000,41.0300000,
     * 114.0820000,41.0300000,
     * 114.0820000,41.0200000,
     * 114.0643000,41.0200000,
     * 0,0,0,
     * 4,
     * 114.0721000,41.0219000,
     * 114.0725000,41.0214000,
     * 114.0707000,41.0203000,
     * 114.0703000,41.0207000,
     * -1,0,0,
     */
    public static String CoordinateDisposeWKT4(String coordinatesStr) {
        String[] coordinatesArry = coordinatesStr.replaceAll(" ", "").split(",");
        //判断当前坐标串用那种方式解析1.十进制度、2.度分秒、3.投影
        Integer analysisType = polygonAnalysis_type(new String[]{coordinatesArry[2], coordinatesArry[3]});
        //面的个数
        Integer polygonNum = Integer.parseInt(coordinatesArry[0]);
        //第一个面的点个数
        Integer pointNum = Integer.parseInt(coordinatesArry[1]);
        //第一个X点
        Integer x = 2;
        //第一个Y点
        Integer y = 3;
        //存放多个面
        List<Polygon> multiPolygonList = new ArrayList<>();
        //存放为洞的面
        List<Polygon> holePolygon = new ArrayList<>();
        for (int i = 0; i < polygonNum; i++) {
            Coordinate[] coordinates = new Coordinate[pointNum];
            for (int j = 0; j < pointNum; j++, x += 2, y += 2) {
                //x点
                String lon = coordinatesArry[x].trim();
                //y点
                String lat = coordinatesArry[y].trim();
                //转为点
                Point point = polygonAnalysis_point(new String[]{lon, lat}, analysisType);
                coordinates[j] = point.getCoordinate();
            }
            //创建面
            Polygon polygon = GeometryUtil.createPolygon(coordinates);
            //判断是多面或带洞的面
            Integer type = Integer.parseInt(coordinatesArry[x]);
            if (type == -1) {
                holePolygon.add(polygon);
            } else {
                multiPolygonList.add(polygon);
            }
            if (i < polygonNum - 1) {
                //第二个或更多面的点数
                pointNum = Integer.parseInt(coordinatesArry[y + 2]);
                x += 4;
                y += 4;
            }
        }

        MultiPolygon multiPolygon = GeometryUtil.createMultiPolygon(multiPolygonList.toArray(new Polygon[multiPolygonList.size()]));
        //存在带洞的情况
        if (holePolygon.size() != 0) {
            List<LinearRing> linearRingList = holePolygon.stream().map(hole -> hole.getExteriorRing()).collect(Collectors.toList());
            //创建带洞的面
            Coordinate[] coordinates = multiPolygon.getCoordinates();
            GeometryFactory geometryFactory = new GeometryFactory();
            LinearRing ring = geometryFactory.createLinearRing(coordinates);
            Polygon polygonWithHoles = GeometryUtil.createPolygonWithHoles(ring, linearRingList.toArray(new LinearRing[holePolygon.size()]));
            multiPolygon = GeometryUtil.createMultiPolygon(new Polygon[]{polygonWithHoles});
        }
        //检查图形的有效性
        if (!multiPolygon.isValid()) {
            return null;
        }
        return multiPolygon.toString();
    }


    // 判断点是否在多边形内
    public  boolean isPointInPolygon(double testX, double testY, String  polygonPoints) {
        boolean intersect=false;
        DecimalFormat df = new DecimalFormat("#.##########");
        df.setGroupingUsed(false);
        Point point= ConvertCoordinates4490(df.format(testX),df.format(testY));
           if (point!=null){
               System.out.println(point.getX()+","+point.getY());
               //获取wkt面积
               String wkt = TransFormUtil.CoordinateDisposeWKT3(polygonPoints);
               Geometry geometry = GeometryUtil.readWKT(wkt);
               if (geometry!=null){
                   intersect= geometry.intersects(point);
               }
           }
        return intersect;
    }


    /**
     * 根据坐标字符串返回拐点坐标对象集合
     *
     * @param coordinatesStr 坐标字符串
     *                       <p>
     *                       2,
     *                       5,
     *                       1,4421028.05,39571109.36,-----4
     *                       2,4421062.05,39571064.36,
     *                       3,4421110.05,39571178.36,
     *                       4,4421088.05,39571236.36,
     *                       5,4421024.05,39571217.36,
     *                       103,47,,1,
     *                       3,
     *                       6,4420876.05,39571372.36,
     *                       7,4420967.05,39571412.36,
     *                       8,4420819.05,39571421.36,
     *                       103,47,,1,
     * @return
     */

    public static List<List<Double>> getKqfwCoordinates(String coordinatesStr) {
        List<List<Double>> polygonList = new ArrayList<>();
        coordinatesStr = coordinatesStr.trim();
        //转换成数组
        String[] coordinatesArry = coordinatesStr.replaceAll(" ", "").split(",");
        //获取第一个元素判断是几个图形
        Integer graphicCount = Integer.parseInt(coordinatesArry[0]);
        //获取第一个图像的坐标个数
        Integer coordinatesCount = Integer.parseInt(coordinatesArry[1]);

        for (int i = 2; i < coordinatesArry.length; ) {

            List<Double> polygon = new ArrayList<>();
            if (coordinatesCount == 0) {
                //x
                //   kqfwCoordinates.setX(coordinatesArry[i]);
                // polygon.add(Double.valueOf(coordinatesArry[i]));
                //Y
                //  kqfwCoordinates.setY(coordinatesArry[i+1]);
                // polygon.add(Double.valueOf(coordinatesArry[i+1]));
//                //拐点
//                kqfwCoordinates.setInflectionPoint("*");
//                if (coordinatesArry[i + 2] != null) {
//                    //矿体标识
//                    kqfwCoordinates.setOreBodyIdentification(coordinatesArry[i + 3]);
//                }
//
//                if (coordinatesArry[i + 3] != null) {
//                    //性质
//                    kqfwCoordinates.setNature(coordinatesArry[i + 3]);
//                }
                if ((i + 4) < coordinatesArry.length) {
                    if (coordinatesArry[i + 4] != null && !coordinatesArry[i + 4].equals("")) {
                        // 获取图像的坐标个数
                        coordinatesCount = Integer.valueOf(coordinatesArry[i + 4]);
                    }
                }
                i = i + 5;
            } else {
                //拐点
                if (coordinatesArry[i + 1] != null) {
                    //x
                    polygon.add(Double.valueOf(coordinatesArry[i + 1]));
                }
                if (coordinatesArry[i + 2] != null && !coordinatesArry[i + 2].equals("")) {
                    //Y
                    polygon.add(Double.valueOf(coordinatesArry[i + 2]));
                }
                coordinatesCount--;
                i = i + 3;
            }
            if (polygon.size() > 0) {
                polygonList.add(polygon);
            }
        }
        return polygonList;
    }


    public   Point ConvertCoordinates4490(String x, String y) {
        Point point = null;
        int dotIndex = x.indexOf('.');
         if (dotIndex == 2){
             String substitution=y;
             y=x;
             x=substitution;

             //将度分秒转成经纬度
             x=String.valueOf(coordinateTranUtil.dmsToWgs84(Double.parseDouble(x))) ;
             y=String.valueOf(coordinateTranUtil.dmsToWgs84(Double.parseDouble(y))) ;
         }
         x=x.replace(",", "");
         y=y.replace(",", "");


        /**
         * 检查输入的度分秒点坐标
         *
         * @param x 经度
         * @param y 纬度
         */
        if (pointDFM(x, y) != null) {
            return pointDFM(x, y);
        }
        /**
         * 检查输入的十进制度点坐标
         *
         * @param x 经度
         * @param y 纬度
         */
        if (pointDecimalism(x, y) != null) {
            return pointDecimalism(x, y);

        }
        /**
         * 检查输入的2000大地点坐标
         *
         * @param x 经度
         * @param y 纬度
         */
        if (pointEPSG4490(x, y) != null) {
            return pointEPSG4490(x, y);
        }


        return point;
    }





    public static void main(String[] args) {

    }


}
